import re
import os
from pydub import AudioSegment


def parse_lrc(lrc_content, offset):
    """解析LRC文件内容，返回按时间排序的(时间戳(毫秒), 歌词)列表"""
    # 正则匹配时间标签和歌词 [mm:ss.SS] 歌词内容
    pattern = r'\[(\d+):(\d{2})\.(\d{2,3})\]([^\n]*)'
    entries = []

    for line in lrc_content.split('\n'):
        matches = re.findall(pattern, line)
        for min, sec, ms, text in matches:
            # 转换为毫秒
            minutes = int(min)
            seconds = int(sec)
            milliseconds = int(ms.ljust(3, '0'))  # 补齐3位毫秒
            total_ms = (minutes * 60 + seconds) * 1000 + milliseconds - offset
            entries.append((total_ms, text.strip()))

    # 按时间戳排序
    entries.sort(key=lambda x: x[0])
    return entries


def sanitize_filename(text, max_length=40):
    """清理文件名中的非法字符并限制长度"""
    # 移除特殊字符
    clean_text = re.sub(r'[\\/*?:"<>|]', "", text)
    # 缩短长文件名
    return clean_text.strip()[:max_length] or "segment"


def split_audio_by_lrc(audio_path, lrc_path, offset, output_dir="output"):
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    # 读取LRC文件
    with open(lrc_path, 'r', encoding='utf-8') as f:
        lrc_content = f.read()
    lyrics = parse_lrc(lrc_content, offset)

    if not lyrics:
        print("错误：未找到有效的LRC时间标签")
        return

    # 加载音频
    audio = AudioSegment.from_file(audio_path)
    total_duration = len(audio)  # 音频总长度(毫秒)

    # 处理每个片段
    for i in range(len(lyrics)):
        start_time = lyrics[i][0]
        end_time = total_duration if i == len(lyrics) - 1 else lyrics[i + 1][0]

        # 确保时间有效性
        if start_time > total_duration:
            continue
        end_time = min(end_time, total_duration)

        # 切割音频
        segment = audio[start_time:end_time]

        # 获取歌词并清理
        lyric_text = lyrics[i][1]
        safe_name = sanitize_filename(lyric_text)

        # 生成文件名 (序号+歌词)
        filename = f"{i + 1:03d}_{safe_name}.mp3"
        output_path = os.path.join(output_dir, filename)

        # 导出片段
        segment.export(output_path, format="mp3")
        print(f"已导出: {filename} ({start_time / 1000:.2f}s-{end_time / 1000:.2f}s)")


if __name__ == "__main__":
    # 配置路径
    audio_file = "data/8DOWN/unit1/Word List Unit 1.mp3"  # 输入音频文件
    lrc_file = "data/8DOWN/unit1/words.lrc"  # LRC歌词文件
    output_folder = "result/8DOWN/unit1"  # 输出目录

    # 配置轨道偏移量(微调，防止音频与字幕不匹配)
    offset = 100
    split_audio_by_lrc(audio_file, lrc_file, offset, output_folder)
